home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 45975 / 45975.xpi / content / remindwords.js < prev    next >
Text File  |  2009-11-23  |  9KB  |  230 lines

  1. /*
  2.  * Copyright (c) 2009 Bui Viet Thanh (thanhbv@gmail.com).
  3.  *
  4.  * This file is part of clicknlearn.
  5.  *
  6.  * clicknlearn is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * clicknlearn is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with clicknlearn.  If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19.  
  20. Components.utils.import("resource://clicknlearn/cnldao.js");
  21. Components.utils.import("resource://clicknlearn/ext/Observers.js");
  22.  
  23. //////////////////////////
  24. function Remind() {
  25. }
  26.  
  27. Remind.prototype.remindCurrentWord = function(){
  28.     var word = CNL.DICLOOKUP.currentWord.replace("'", "''");
  29.     var remind = CNL.currentDoc.getElementById('remindbox').value.replace("'", "''");
  30.     CNL.DICLOOKUP.currentWord.replace("'", "''");
  31.     var r = {"id": word, "remind": remind, "originalUrl": content.location.href, "read": 0};
  32.     CNL_DAO.create(r);
  33.     Observers.notify("cnl_wordAddOrModify", word);
  34.  
  35.     this.highlightWord(CNL.DICLOOKUP.currentWord);
  36.     CNL.DICLOOKUP.clearAll();
  37. }
  38.  
  39. Remind.prototype.removeCurrentWord = function(){
  40.     CNL_DAO.setWordRead(CNL.DICLOOKUP.currentWord);
  41.     Observers.notify("cnl_wordAddOrModify", CNL.DICLOOKUP.currentWord);
  42. //    this.unHighlightWord(CNL.DICLOOKUP.currentWord);
  43.     CNL.DICLOOKUP.clearAll();
  44. }
  45.  
  46. Remind.prototype.nodeDepth = function(node){
  47.     var depth = 0;
  48.     var body = window.content.document.body;
  49.     while(node != body){
  50.         depth++;
  51.         node = node.parentNode;
  52.     }
  53.     return depth;
  54. }
  55. Remind.prototype.surround = function(range){
  56.     //range.startContainer is always TextNode?
  57.     var doc = window.content.document;
  58.     var surroundNode = doc.createElement("span");
  59.     surroundNode.setAttribute("class", "clicknlearnRemind");
  60.     if(range.startContainer.parentNode == range.endContainer.parentNode){
  61.         range.surroundContents(surroundNode);
  62.         return;
  63.     }
  64.     //find commond parent node of the start point & end point
  65.     var s = range.startContainer.parentNode;
  66.     var sdepth = this.nodeDepth(s);
  67.     var e = range.endContainer.parentNode;
  68.     var edepth = this.nodeDepth(e);
  69.     for(;sdepth > edepth; sdepth--)
  70.         s = s.parentNode;
  71.     for(;edepth > sdepth; edepth--)
  72.         e = e.parentNode;
  73.     while(s != e){
  74.         s = s.parentNode;
  75.         e = e.parentNode;
  76.     }
  77.     var p = s;//common parent
  78.     //do surround
  79.     s = range.startContainer;
  80.     e = range.endContainer;
  81.     var eOffset = range.endOffset;
  82.     while(s.parentNode != p){
  83.         range.setEnd(s.parentNode, s.parentNode.childNodes.length);
  84.         range.surroundContents(surroundNode.cloneNode(true));
  85.         range.setStartAfter(s.parentNode);
  86.         s = s.parentNode;
  87.     }
  88.  
  89.     s = range.startContainer;
  90.     var sOffset = range.startOffset;
  91.     range.setEnd(e, eOffset);
  92.     while(e.parentNode != p){        
  93.         range.setStart(e.parentNode, 0);
  94.         range.surroundContents(surroundNode.cloneNode(true));
  95.         range.setEndBefore(e.parentNode);
  96.         e = e.parentNode;
  97.     }
  98.  
  99.     range.setStart(s, sOffset);
  100.     range.surroundContents(surroundNode);
  101. }
  102.  
  103. /**
  104.  * See: nsIFind - http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/interfaces/nsIFind
  105.  *      Range - http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
  106.  */
  107. Remind.prototype.highlightWords = function(){
  108.     var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
  109.             .QueryInterface(Components.interfaces.nsIFind);
  110.  
  111.     var doc = window.content.document;
  112.     var body = doc.body;
  113.  
  114.     var count = body.childNodes.length;
  115.     var mSearchRange = doc.createRange();
  116.     var mStartPt = doc.createRange();
  117.     var mEndPt = doc.createRange();
  118.     mSearchRange.setStart(body, 0);
  119.     mSearchRange.setEnd(body, count);
  120.     mEndPt.setStart(body, count);
  121.     mEndPt.setEnd(body, count);    
  122.  
  123.     var statement = CNL_DAO.selectUnreadWordsStm();
  124.     //if range represent 'in' in a word 'inova' then we should not highlight it
  125.     var isRangeAWord, i;
  126.     statement.executeAsync({
  127.         handleResult: function(aResultSet) {
  128.             for (var row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) {
  129.                 var word = row.getResultByName("word");
  130.                 var rs = new Array();
  131.  
  132.                 mStartPt.setStart(body, 0);
  133.                 mStartPt.setEnd(body, 0);
  134.                 var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
  135.                 while(foundRange != null){
  136.                     //TODO haven't tested
  137.                     //check start of a word:
  138. //                        alert(word + ": start: " + foundRange.startContainer.nodeType + ", " + foundRange.startOffset +
  139. //                              ", end: " + foundRange.endContainer.nodeType + ", " + foundRange.endOffset);
  140.                     //TODO foundRange.startContainer & endContainer is always TEXT_NODE???
  141.                     if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
  142.                         isRangeAWord = true;
  143.                     else{
  144.                         i = foundRange.startOffset;
  145.                         isRangeAWord = i == 0
  146.                             || ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
  147.                     }
  148.                     //check end of a word:
  149.                     //Only check if check start successfully
  150.                     if(isRangeAWord)
  151.                         if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
  152.                             i = foundRange.endOffset;
  153.                             isRangeAWord = i == foundRange.endContainer.textContent.length
  154.                                 || ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
  155.                         }
  156.                     if(isRangeAWord)
  157.                         rs[rs.length] = foundRange;
  158.                     mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
  159.                     mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
  160.                     foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
  161.                 }
  162.  
  163.                 for(i=0; i<rs.length; i++)
  164.                     CNL.REMIND.surround(rs[i]);
  165.             }
  166.         },
  167.         handleError: function(aError) {
  168. //            print("Error: " + aError.message);
  169.         },
  170.         handleCompletion: function(aReason) {
  171. //            if (aReason != Components.interfaces.mozIStorageStatementCallback.REASON_FINISHED)
  172. //                print("Query canceled or aborted!");
  173.         }
  174.     });
  175. }
  176.  
  177. Remind.prototype.highlightWord = function(word){
  178.     var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
  179.             .QueryInterface(Components.interfaces.nsIFind);
  180.  
  181.     var doc = window.content.document;
  182.     var body = doc.body;
  183.  
  184.     var count = body.childNodes.length;
  185.     var mSearchRange = doc.createRange();
  186.     var mStartPt = doc.createRange();
  187.     var mEndPt = doc.createRange();
  188.     mSearchRange.setStart(body, 0);
  189.     mSearchRange.setEnd(body, count);
  190.     mEndPt.setStart(body, count);
  191.     mEndPt.setEnd(body, count);
  192.  
  193.     //if range represent 'in' in a word 'inova' then we should not highlight it
  194.     var isRangeAWord, i;
  195.     
  196.     var rs = new Array();
  197.  
  198.     mStartPt.setStart(body, 0);
  199.     mStartPt.setEnd(body, 0);
  200.     var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
  201.     while(foundRange != null){
  202.         //TODO haven't tested
  203.         //check start of a word:
  204.         //TODO foundRange.startContainer & endContainer is always TEXT_NODE???
  205.         if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
  206.             isRangeAWord = true;
  207.         else{
  208.             i = foundRange.startOffset;
  209.             isRangeAWord = i == 0
  210.                 || ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
  211.         }
  212.         //check end of a word:
  213.         //Only check if check start successfully
  214.         if(isRangeAWord)
  215.             if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
  216.                 i = foundRange.endOffset;
  217.                 isRangeAWord = i == foundRange.endContainer.textContent.length
  218.                     || ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
  219.             }
  220.         if(isRangeAWord)
  221.             rs[rs.length] = foundRange;
  222.         mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
  223.         mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
  224.         foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
  225.     }
  226.  
  227.     for(i=0; i<rs.length; i++)
  228.         CNL.REMIND.surround(rs[i]);
  229. }
  230.